package cn.topevery.garden.entity.bo;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author LiuHui
 * @description: TODO
 * @date 2024-01-10
 */
@Data
@Component
@ConfigurationProperties(prefix = "hw.config.login-verify")
public class LoginFailCacheBO {

    /** 登陆失败次数 **/
    private int failCount;
    /** 锁定期限至 **/
    private LocalDateTime lockExpireAt;
    /** 登录用户名 **/
    private String loginName;
    /** IP地址 **/
    private String ip;
    /** 第一次会话时间 **/
    private LocalDateTime firstTime;
    /** 最后一次会话时间 **/
    private LocalDateTime lastTime;

    private boolean lock;

    /** 最大失败次数 **/
    public static int MAX_FAIL_COUNT = 3;
    /** 锁定时长（秒） **/
    public static long LOCK_TIME_20 = 40;
    /** root用户锁定时长（秒） **/
    public static long LOCK_TIME_30 = 60;
    /** 用户前缀 **/
    public static String PREFIX = "USER_";

    @Value("${maxFailCount:3}")
    public void setMaxFailCount(int maxFailCount) {
        LoginFailCacheBO.MAX_FAIL_COUNT = maxFailCount;
    }
    @Value("${lockTime:40}")
    public void setLockTime(int lockTime) {
        LoginFailCacheBO.LOCK_TIME_20 = lockTime;
    }
    @Value("${lockTime2:60}")
    public void setLockTime2(int lockTime) {
        LoginFailCacheBO.LOCK_TIME_30 = lockTime;
    }

    public LoginFailCacheBO() {
    }

    public LoginFailCacheBO(String loginName) {
        this(loginName, null);
    }

    public LoginFailCacheBO(String loginName, String ip) {
        this(loginName, LocalDateTime.now(), ip);
    }

    public LoginFailCacheBO(String loginName, LocalDateTime firstTime, String ip) {
        this.loginName = loginName;
        this.firstTime = firstTime;
        this.ip = ip;
        this.lastTime = firstTime;
        this.failCount = 1;
    }

    public synchronized void addFailCount(LocalDateTime now) {
        this.lastTime = now;
        int count = ++this.failCount;
        boolean lock = count > 0 && (count % MAX_FAIL_COUNT == 0);
        this.lock = lock;
        if (lock) {
            this.lockExpireAt = now.plusSeconds("admin".equals(this.loginName) ? LOCK_TIME_30 : LOCK_TIME_20);
        }
    }

    public boolean isLock(LocalDateTime time) {
        return this.lock && this.lockExpireAt.isAfter(time);
    }
}
